/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkRtspStreamSource.h"
#include "MkUtil/MkLog.h"

CMkRtspStreamSource::CMkRtspStreamSource(const MkMediaSourceType& SourceType)
    : CMkMediaSource(SourceType)
    , m_nEsMaxLen(Len1M) //max es packet len 1M
    , m_nEsOffset(0)
{
    m_pMallocBuf = (Uint8*)malloc(m_nEsMaxLen);
    m_pEsBuffer = m_pMallocBuf + Len16;
}

Uint32 CMkRtspStreamSource::ParseH264RtpPacket(const CMkRtpPacket& RtpPacket)
{
    const Uint8 *pData = RtpPacket.GetPayloadData();
    Uint32 nLen = RtpPacket.GetPayloadLength();
    Uint8 H264PacketType = (pData[0] & 0x1f);
    Uint8 NaluType = 0;
    m_VideoEsPacket.CodecType = MkCodecH264;
    m_VideoEsPacket.Pts = m_VideoEsPacket.Dts = RtpPacket.GetTimeStamp() / (MkDefaultClockRate / 1000);
    //https://www.rfc-editor.org/rfc/rfc6184.html#section-5.4
    if (MkH264PacketUnknow < H264PacketType && H264PacketType <= MkH264PacketSingle) { //packet signal
        memcpy(m_pEsBuffer + m_nEsOffset, pData, nLen);
        CMkMediaUtil::Get264NaluType(pData[0], NaluType);
        if (MkH264NalSps == NaluType) {
            m_VideoParam.SetSps(MkString((Int8*)pData, nLen));
        } else if (MkH264NalPps == NaluType) {
            m_VideoParam.SetPps(MkString((Int8*)pData, nLen));
        }
        m_VideoEsPacket.BufferList.Append(m_pEsBuffer + m_nEsOffset, nLen);
        m_nEsOffset += nLen;
        if (MkH264NalSlice == NaluType
            || MkH264NalIdrSlice == NaluType) {
            m_VideoEsPacket.bKeyPacket = MkH264NalIdrSlice == NaluType;
            OnReadEsPacket(m_VideoEsPacket);
            m_VideoEsPacket.BufferList.Clear();
            m_nEsOffset = 0;
        }
    } else if (MkH264PacketFuA == H264PacketType ||
        MkH264PacketFuB == H264PacketType) {
        /*
             0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        | FU indicator  |   FU header   |                               |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
        |                                                               |
        |                         FU payload                            |
        |                                                               |
        |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                               :...OPTIONAL RTP padding        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        NaluType = (pData[1] & 0x0F);
        Uint8 Nalu = (pData[0] & 0xE0) | (pData[1] & 0x0F);
        Uint8 PacketType = pData[1] & 0xF0;
        //first packet
        m_VideoEsPacket.bKeyPacket = MkH264NalIdrSlice == NaluType;
        if (0x80 == PacketType) {
            m_pFuBegin = m_pEsBuffer + m_nEsOffset;
            memcpy(m_pEsBuffer + m_nEsOffset, &Nalu, 1);
            m_nEsOffset++;
            m_nFuLen = 1;
        }
        memcpy(m_pEsBuffer + m_nEsOffset, pData + 2, nLen - 2);
        m_nEsOffset += nLen - 2;
        m_nFuLen += nLen - 2;
        //end packet
        if (0x40 == PacketType) {
            if (nullptr != m_pFuBegin) {
                m_VideoEsPacket.BufferList.Append(m_pFuBegin, m_nFuLen);
                m_nEsOffset = 0;
                m_nFuLen = 0;
                m_pFuBegin = nullptr;
                OnReadEsPacket(m_VideoEsPacket);
                m_VideoEsPacket.BufferList.Clear();
            } else {
                MkWarningLog("not recv fu header\n");
            }
        }
        //https://www.rfc-editor.org/rfc/rfc6184.html#section-5.7.1
    } else if (MkH264PacketStapA == H264PacketType) {
        /*
             0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                          RTP Header                           |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |STAP-A NAL HDR |         NALU 1 Size           | NALU 1 HDR    |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                         NALU 1 Data                           |
        :                                                               :
        +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |               | NALU 2 Size                   | NALU 2 HDR    |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                         NALU 2 Data                           |
        :                                                               :
        |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                               :...OPTIONAL RTP padding        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        Uint32 nOffset = 1;
        Uint16 NaluSize = 0;
        while (nOffset < nLen) {
            NaluSize = (pData[nOffset] << 8) | pData[NaluSize + 1];
            if (NaluSize + 2 + nOffset > nLen) {
                break;
            }
            nOffset += 2;
            memcpy(m_pEsBuffer + m_nEsOffset, pData + nOffset, NaluSize);
            CMkMediaUtil::Get264NaluType(pData[nOffset], NaluType);
            if (MkH264NalSps == NaluType) {
                m_VideoParam.SetSps(MkString((Int8*)pData + nOffset, NaluSize));
            } else if (MkH264NalPps == NaluType) {
                m_VideoParam.SetPps(MkString((Int8*)pData + nOffset, NaluSize));
            }
            m_VideoEsPacket.BufferList.Append(m_pEsBuffer + m_nEsOffset, NaluSize);
            m_nEsOffset += NaluSize;
            nOffset += NaluSize;
        }
    } else if (MkH264PacketStapB == H264PacketType) {
        /*
             0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                          RTP Header                           |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |STAP-B NAL HDR | DON                           | NALU 1 Size   |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        | NALU 1 Size   | NALU 1 HDR    | NALU 1 Data                   |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
        :                                                               :
        +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |               | NALU 2 Size                   | NALU 2 HDR    |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                       NALU 2 Data                             |
        :                                                               :
        |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                               :...OPTIONAL RTP padding        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        Uint32 nOffset = 1;
        Uint16 DecoderOrderNumber = (pData[1] << 8)&pData[2];
        nOffset += 2;
        Uint16 NaluSize = 0;
        Uint8* pBegin = nullptr;
        while (nOffset < nLen) {
            NaluSize = (pData[nOffset] << 8) | pData[NaluSize + 1];
            if (NaluSize + 2 + nOffset > nLen) {
                break;
            }
            nOffset += 2;
            memcpy(m_pEsBuffer + m_nEsOffset, pData + nOffset, NaluSize);

            CMkMediaUtil::Get264NaluType(pData[nOffset], NaluType);
            if (MkH264NalSps == NaluType) {
                m_VideoParam.SetSps(MkString((Int8*)pData + nOffset, NaluSize));
            } else if (MkH264NalPps == NaluType) {
                m_VideoParam.SetPps(MkString((Int8*)pData + nOffset, NaluSize));
            }
            m_VideoEsPacket.BufferList.Append(m_pEsBuffer + m_nEsOffset, NaluSize);
            m_nEsOffset += NaluSize;
            nOffset += NaluSize;
        }
    } else if (MkH264PacketMtap16 == H264PacketType) {
        /*
             0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                          RTP Header                           |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |MTAP16 NAL HDR |  decoding order number base   | NALU 1 Size   |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |  NALU 1 Size  |  NALU 1 DOND  |       NALU 1 TS offset        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |  NALU 1 HDR   |  NALU 1 DATA                                  |
        +-+-+-+-+-+-+-+-+                                               +
        :                                                               :
        +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |               | NALU 2 SIZE                   |  NALU 2 DOND  |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |       NALU 2 TS offset        |  NALU 2 HDR   |  NALU 2 DATA  |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
        :                                                               :
        |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                               :...OPTIONAL RTP padding        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        Uint32 nOffset = 1;
        Uint16 DecoderOrderNumber = (pData[1] << 8)&pData[2];
        nOffset += 2;
        Uint16 NaluSize = 0;
        Uint8* pBegin = nullptr;
        while (nOffset < nLen) {
            NaluSize = (pData[nOffset] << 8) | pData[nOffset + 1];
            if (NaluSize + 2 + nOffset > nLen) {
                break;
            }
            nOffset += 2;
            Uint8 Dond = pData[nOffset++];
            //ts offset
            m_VideoEsPacket.Pts += (pData[nOffset] << 8) | pData[nOffset + 1];
            m_VideoEsPacket.Dts = m_VideoEsPacket.Pts;
            nOffset += 2;
            memcpy(m_pEsBuffer + m_nEsOffset, pData + nOffset, NaluSize);

            CMkMediaUtil::Get264NaluType(pData[nOffset], NaluType);
            if (MkH264NalSps == NaluType) {
                m_VideoParam.SetSps(MkString((Int8*)pData + nOffset, NaluSize));
            } else if (MkH264NalPps == NaluType) {
                m_VideoParam.SetPps(MkString((Int8*)pData + nOffset, NaluSize));
            }
            m_VideoEsPacket.BufferList.Append(m_pEsBuffer + m_nEsOffset, NaluSize);
            m_nEsOffset += NaluSize;
            nOffset += NaluSize;
        }
    } else if (MkH264PacketMtap24 == H264PacketType) {
        /*
         0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                          RTP Header                           |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |MTAP24 NAL HDR |  decoding order number base   | NALU 1 Size   |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |  NALU 1 Size  |  NALU 1 DOND  |       NALU 1 TS offs          |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |NALU 1 TS offs |  NALU 1 HDR   |  NALU 1 DATA                  |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
        :                                                               :
        +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |               | NALU 2 SIZE                   |  NALU 2 DOND  |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |       NALU 2 TS offset                        |  NALU 2 HDR   |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |  NALU 2 DATA                                                  |
        :                                                               :
        |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                               :...OPTIONAL RTP padding        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        Uint32 nOffset = 1;
        Uint16 DecoderOrderNumber = (pData[1] << 8)&pData[2];
        nOffset += 2;
        Uint16 NaluSize = 0;
        Uint8* pBegin = nullptr;
        while (nOffset < nLen) {
            NaluSize = (pData[nOffset] << 8) | pData[nOffset + 1];
            if (NaluSize + 2 + nOffset > nLen) {
                break;
            }
            nOffset += 2;
            Uint8 Dond = pData[nOffset++];
            //ts offset
            m_VideoEsPacket.Pts += (pData[nOffset] << 16) | (pData[nOffset + 1] << 8) | pData[nOffset + 2];
            m_VideoEsPacket.Dts = m_VideoEsPacket.Pts;
            nOffset += 3;
            memcpy(m_pEsBuffer + m_nEsOffset, pData + nOffset, NaluSize);

            CMkMediaUtil::Get264NaluType(pData[nOffset], NaluType);
            if (MkH264NalSps == NaluType) {
                m_VideoParam.SetSps(MkString((Int8*)pData + nOffset, NaluSize));
            } else if (MkH264NalPps == NaluType) {
                m_VideoParam.SetPps(MkString((Int8*)pData + nOffset, NaluSize));
            }
            m_VideoEsPacket.BufferList.Append(m_pEsBuffer + m_nEsOffset, NaluSize);
            m_nEsOffset += NaluSize;
            nOffset += NaluSize;
        }
    }
    return NoneError;
}

//https://datatracker.ietf.org/doc/html/rfc7798#section-4.4
Uint32 CMkRtspStreamSource::ParseH265RtpPacket(const CMkRtpPacket& RtpPacket)
{
    Uint8 NaluType = 0;
    const Uint8 *pData = RtpPacket.GetPayloadData();
    Uint32 nLen = RtpPacket.GetPayloadLength();
    CMkMediaUtil::Get265NaluType(pData[0], NaluType);
    m_VideoEsPacket.Dts = m_VideoEsPacket.Pts = RtpPacket.GetTimeStamp() / (MkDefaultClockRate / 1000);
    m_VideoEsPacket.CodecType = MkCodecH265;
    if (MkHevcPacketPaci == NaluType) {
        /*
            0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |    PayloadHdr (Type=49)       |   FU header   | DONL (cond)   |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
       | DONL (cond)   |                                               |
       |-+-+-+-+-+-+-+-+                                               |
       |                         FU payload                            |
       |                                                               |
       |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                               :...OPTIONAL RTP padding        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        Uint8 PacketType = pData[2] & 0xC0;
        NaluType = pData[2] & 0x3F;
        //first packet
        m_VideoEsPacket.bKeyPacket = MkHevcNalIdrWRadl == NaluType || MkHevcNalIdrNLp == NaluType;
        if (0x80 == PacketType) {
            m_pFuBegin = m_pEsBuffer + m_nEsOffset;
            Uint8 pHead = NaluType << 1;
            memcpy(m_pEsBuffer + m_nEsOffset, &pHead, 1);
            m_nEsOffset++;
            memcpy(m_pEsBuffer + m_nEsOffset, &pData[1], 1);
            m_nEsOffset++;
            m_nFuLen = 2;
        }
        if (!m_pFuBegin) {
            return SystemError;
        }
        memcpy(m_pEsBuffer + m_nEsOffset, pData + 3, nLen - 3);
        m_nEsOffset += nLen - 3;
        m_nFuLen += nLen - 3;
        // end packet
        if (0x40 == PacketType) {
            m_VideoEsPacket.BufferList.Append(m_pFuBegin, m_nFuLen);
            m_nEsOffset = 0;
            m_nFuLen = 0;
            m_pFuBegin = nullptr;
            OnReadEsPacket(m_VideoEsPacket);
            m_VideoEsPacket.BufferList.Clear();
        }
    } else if (MkHevcPacketAp == NaluType) {
        /*
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                          RTP Header                           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |   PayloadHdr (Type=48)        |         NALU 1 Size           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          NALU 1 HDR           |                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+         NALU 1 Data           |
       |                   . . .                                       |
       |                                                               |
       +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  . . .        | NALU 2 Size                   | NALU 2 HDR    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       | NALU 2 HDR    |                                               |
       +-+-+-+-+-+-+-+-+              NALU 2 Data                      |
       |                   . . .                                       |
       |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                               :...OPTIONAL RTP padding        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        Uint32 nOffset = 1;
        Uint8 *pBegin = nullptr;
        while (nOffset < nLen) {
            Uint16 NaluSize = (pData[nOffset] << 8) | pData[nOffset];
            if (NaluSize + nOffset > nLen) {
                break;
            }
            nOffset += 2;
            memcpy(m_pEsBuffer + m_nEsOffset, pData + nOffset, NaluSize);
            m_VideoEsPacket.BufferList.Append(pData + nOffset, NaluSize);
            m_nEsOffset += NaluSize;
            nOffset += NaluSize;
        }
    } else { //single packet
        /*
            0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           PayloadHdr          |      DONL (conditional)       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       |                  NAL unit payload data                        |
       |                                                               |
       |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                               :...OPTIONAL RTP padding        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        */
        memcpy(m_pEsBuffer + m_nEsOffset, pData, nLen);
        if (MkHevcNalVps == NaluType) {
            m_VideoParam.SetVps(MkString((Int8*)pData, nLen));
        }
        if (MkHevcNalSps == NaluType) {
            m_VideoParam.SetSps(MkString((Int8*)pData, nLen));
        }
        if (MkHevcNalPps == NaluType) {
            m_VideoParam.SetPps(MkString((Int8*)pData, nLen));
        }
        m_VideoEsPacket.BufferList.Append(m_pEsBuffer + m_nEsOffset, nLen);
        m_nEsOffset += nLen;
        if (MkHevcNalTrailR == NaluType
            || MkHevcNalIdrWRadl == NaluType
            || MkHevcNalIdrNLp == NaluType) {
            m_VideoEsPacket.bKeyPacket = MkHevcNalIdrWRadl == NaluType || MkHevcNalIdrNLp == NaluType;
            OnReadEsPacket(m_VideoEsPacket);
            m_VideoEsPacket.BufferList.Clear();
            m_nEsOffset = 0;
        }
    }
    return NoneError;
}

Uint32 CMkRtspStreamSource::ParseAacRtpPacket(const CMkRtpPacket& RtpPacket)
{
    MkEsPacket EsPacket;
    EsPacket.CodecType = MkCodecAac;
    EsPacket.Pts = EsPacket.Dts = RtpPacket.GetTimeStamp() / (MkDefaultClockRate / 1000);
    EsPacket.bKeyPacket = TRUE;
    EsPacket.BufferList.Append(RtpPacket.GetPayloadData(), RtpPacket.GetPayloadLength());
    OnReadEsPacket(EsPacket);
    return NoneError;
}

CMkRtspStreamSource::~CMkRtspStreamSource()
{
    MkFree(m_pMallocBuf);
}